package com.sduept.nwld.dataserver.manager.faultforecast;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 朴素贝叶斯分类实现数据分类
 */
public class NaiveBayesCode {

	/**
	 * 根据已有样本，利用朴素贝叶斯分类器算法预测所传入数据是否是故障
	 * 比较不同类别 p(w0,w1,w2...wn | ci)*p(ci) 的大小 
	 * p(w0,w1,w2...wn | ci) = p(w0|ci)*p(w1|ci)*p(w2|ci)...
	 * @param sampleMap 样本（key：类型，value：数据集）
	 * @param dataSize 总数据个数
	 * @param dataArr 要预测数据，值的顺序和sampleMap的value数据集保持一致（如：样本数据是[长度，宽度，高度]，则要预测数据顺序也是[长度，宽度，高度]）
	 * @return 要预测数据属于各类别的概率（key：类型，value：概率）
	 */
	public static Map<String, Double> faultForcast(Map<String, List<double[]>> sampleMap, int dataSize, double[] dataArr){
		
		Map<String, Double> resultMap = new HashMap<String, Double>();//要预测数据属于各类别的概率（key：类型，value：概率）
		if(sampleMap.size() > 0 && dataSize > 0 && dataArr.length > 0){
			
			for(Map.Entry<String, List<double[]>> entry : sampleMap.entrySet()){
				
				double naiveBayes = (double)entry.getValue().size()/(double)dataSize;//初始值为p（类概率）
				double[] independentArr = compute(entry.getValue(), dataArr);//计算各独立概率
				for(int i = 0; i < independentArr.length; i++){
					
					naiveBayes = naiveBayes * independentArr[i];
				}
				
				resultMap.put(entry.getKey(), naiveBayes);
			}
		}
		return resultMap;
	}
	
	/**
	 * 计算各独立概率
	 * @param sampleList 样本数据
	 * @param dataArr 要预测数据
	 * @return 各独立概率，顺序和传入数据一致
	 */
	public static double[] compute(List<double[]> sampleList, double[] dataArr){
		
		int arrSize = dataArr.length;//数组大小
		int[] dataTime = new int[arrSize];//dataArr各数据在sampleList中出现的次数，顺序和传入数据一致
		for(double[] sampleArr : sampleList){
			
			for(int i = 0; i < sampleArr.length; i++){
				
				if(sampleArr[i] == dataArr[i]){
					dataTime[i] += 1;
				}
			}
		}
		double[] independentArr = new double[arrSize];//各独立概率，顺序和传入数据一致
		for(int i = 0; i < arrSize; i++){
			
			if(dataTime[i] == 0){//拉普拉斯平滑
				independentArr[i] = (double)(dataTime[i] + 1)/(double)(sampleList.size() + 1);
			}else{
				independentArr[i] = (double)dataTime[i]/(double)sampleList.size();
			}
		}
		return independentArr;
	}
	
}
